package com.liu.demo1.testDemo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * @author liusiyu
 * @ClassName ArrayOrLinked
 * @date 2022年01月18日 10:12
 */
public class ArrayOrLinked {
    static List<Integer> array = new ArrayList<>();
    static List<Integer> linked = new LinkedList<>();

    public static void main(String[] args) {
        
        //分别给两个list新增1w的数据
        for (int i = 0; i < 10000; i++) {
            array.add(i);
            linked.add(i);
        }
        //获取两者随机访问的时间
        System.out.println("array time :"+getTime(array));
        System.out.println("linked time :"+getTime(linked));
        //获得两者插入的时间
        System.out.println("array insert time :"+insertTime(array));
        System.out.println("linked insert time :"+insertTime(linked));
        //数组遍历的三种方式
        String []s = new String[1];
        Arrays.stream(s).forEach(a -> System.out.println(s));
        Arrays.asList(s).stream().forEach(System.out::println);
        Stream.of(s).forEach(System.out::println);

        Map<String,String> map = new HashMap<>();
        Iterator<Map.Entry<String,String>> iterator = map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String,String> entry = iterator.next();
            String a = entry.getKey();
        }
    }

    public static long getTime(List<Integer> list){
        long time = System.currentTimeMillis();
        for(int i = 0; i < 10000; i++){
            int index = Collections.binarySearch(list, list.get(i));
            if(index != i){
                System.out.println("ERROR!");
            }
        }
        return System.currentTimeMillis()-time;
    }

    public static long insertTime(List<Integer> list){
        long num = 100000;
        int index = 10000;
        long time = System.currentTimeMillis();
        for (int i = 0; i < num; i++) {
            list.add(index,i);
        }
        return System.currentTimeMillis()-time;
    }
    //在数据量插入数据量及基数较大的情况下linkedlist会从头循环找到角标然后插入，越靠后花费时间越长，
    // arraylist的变化不大，但是基础花费时间较长，如果角标越靠后，arraycopy的数组越小，花费越小，不过总体变化很小
    //总体来说，数据量小的情况下，差距很小，但是查询array快，如果数据量较大（几万以上）array变化不大，linked越靠后越花时间，会反超array
    //数据量大（基数和新增数都较大）的情况下,使用ArrayList,考虑是否会频繁触发扩容,使用LinkedList是否会深度遍历.
    /*
    *差距明显的前提基于两个外部条件
    * 1、list基数和插入数据量都很大
    * 2、插入角标位置有一个临界点，两个list的速度差不多，linked随角标增加线性增长，增长速度较快，array随角标增加线性减少，减少速度较慢，差距很小
    * 3、影响array的主要因素为arraycopy，影响linked主要原因为循环遍历
    */
}
